#pragma once

#define QT_NO_SIGNALS_SLOTS_KEYWORDS

// #include <glad/glad.h>

#include <QQuickItem>
#include <QRunnable>
#include <QSurfaceFormat>
#include <QSize>

#include <algorithm/shared/data/scene/Heliostat.h>

#include <chrono>
#include <shared_mutex>

namespace solar
{
    class SceneRenderer;
    struct AnalyticalPipelineParam;

    class SceneRendererAdapter : public QQuickItem
    {
            Q_OBJECT
            QML_ELEMENT
        public:
            explicit SceneRendererAdapter(QQuickItem* parent = nullptr);
            ~SceneRendererAdapter() override;
            Q_DISABLE_COPY_MOVE(SceneRendererAdapter)
            Q_INVOKABLE void setParentSizeWidth(int new_width);
            Q_INVOKABLE void setParentSizeHeight(int new_height);
            Q_INVOKABLE void rotateLookAtCenterHorizontal(float degree);
            Q_INVOKABLE void rotateLookAtCenterVertical(float degree);
            Q_INVOKABLE void rotateLookAtCenter(float horizontal_degree, float vertical_degree);
            Q_INVOKABLE void updateFocusCenter();
            Q_INVOKABLE void updateSunRayDirection();
            // Only for testing
            Q_INVOKABLE void increaseTime();
            Q_INVOKABLE void moveCameraCenter(float delta_x, float delta_y, float delta_z);
            Q_INVOKABLE void moveLookAtCenter(float delta_x, float delta_y, float delta_z);

            void updateScene(AnalyticalPipelineParam* params);

        public Q_SLOTS:
            void sync();
            void cleanup();

        private Q_SLOTS:
            void handleWindowChanged(QQuickWindow* win) const;

        private:
            void releaseResources() override;

            SceneRenderer* renderer_;
            QSurfaceFormat format_;
            QSize parent_size_;
            std::shared_mutex parent_size_mutex_;
            std::chrono::hh_mm_ss<std::chrono::seconds> current_time_;

            class CleanupJob : public QRunnable
            {
                public:
                    CleanupJob(SceneRenderer* renderer);
                    void run() override;

                private:
                    SceneRenderer* renderer_;
            };
    };
} // namespace solar
